/*
 * errors.c
 *
 *  Created on: 29/apr/2014
 *      Author: kappa
 */
#include "errors.h"
#include <stdarg.h>

extern int errno;
/****************************************************************************
 * @function 		: notifyError											*
 * @descr			: Esegue la decodifica di un errore sia di sistema 		*
 * 					  che della logica del programma.Riporta un messaggio 	*
 * 					  personalizzato ed un eventuale messaggio di sistema 	*
 * 					  sia sullo stdout che sul file di log se presente. 	*
 * 					   														*
 * @param err_code	: codice dell'errore interno al programma				*
 * @param errparams	: parametri del messaggio personalizzato				*
 * @param pdim		: dimensione dell'array errparams						*
 * @param exitflag	: flag di terminazione del programma (errore grave)		*
 ****************************************************************************/

void notifyError(ERRCODE err_code, int exitflag, int pdim, ... ){
	va_list parameters;

	int k = 0, size = 0;
	LEVEL level = INFO_LEV;
	char *msg = NULL, *temp = NULL, *composedmsg = NULL, *param;
#ifdef _WIN32
	DWORD errnumber = GetLastError();
	LPVOID lpMsgBuf;
#endif
	
	switch(err_code){

	case ERR_CFG_OPEN:
		size = strlen(MSG_HEAD)+strlen(MSG_CFG_OPEN)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_CFG_OPEN);
		level = ERR_LEV;
		break;

	case ERR_CFG_CLOSE:
		size = strlen(MSG_HEAD)+strlen(MSG_CFG_CLOSE)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_CFG_CLOSE);
		level = ERR_LEV;
		break;

	case ERR_CFG_READ:
		size = strlen(MSG_HEAD)+strlen(MSG_CFG_READ)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_CFG_READ);
		level = ERR_LEV;
		break;

	case ERR_CFG_WRITE:
		size = strlen(MSG_HEAD)+strlen(MSG_CFG_WRITE)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_CFG_WRITE);
		level = ERR_LEV;
		break;

	case ERR_SOCK_OPEN:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCK_OPEN)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCK_OPEN);
		level = ERR_LEV;
		break;

	case ERR_SOCK_CLOSE:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCK_CLOSE)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCK_CLOSE);
		level = ERR_LEV;
		break;

	case ERR_SOCK_BIND:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCK_BIND)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCK_BIND);
		level = ERR_LEV;
		break;

	case ERR_SOCK_LISTEN:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCK_LISTEN)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCK_LISTEN);
		level = ERR_LEV;
		break;

	case ERR_SOCK_CONNECT:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCK_CONNECT)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCK_CONNECT);
		level = ERR_LEV;
		break;

	case ERR_SOCK_ACCEPT:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCK_ACCEPT)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCK_ACCEPT);
		level = ERR_LEV;
		break;

	case ERR_SOCK_WRITE:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCK_WRITE)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCK_WRITE);
		level = ERR_LEV;
		break;

	case ERR_SOCK_READ:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCK_READ)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCK_READ);
		level = ERR_LEV;
		break;

	case ERR_SOCKINFO_READ:
		size = strlen(MSG_HEAD)+strlen(MSG_SOCKINFO_READ)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SOCKINFO_READ);
		level = ERR_LEV;
		break;

	case USER_END:
		size = strlen(MSG_HEAD)+strlen(MSG_USR_END)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_USR_END);
		level = ERR_LEV;
		break;

	case ERR_NO_MEM:
		size = strlen(MSG_HEAD)+strlen(MSG_NO_MEM)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_USR_END);
		level = ERR_LEV;
		break;

	case ERR_DEC_MOD:
		size = strlen(MSG_HEAD)+strlen(MSG_DEC_MOD)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_DEC_MOD);
		level = ERR_LEV;
		break;

	case ERR_DEC_CFG:
		size = strlen(MSG_HEAD)+strlen(MSG_DEC_CFG)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_DEC_CFG);
		level = ERR_LEV;
		break;

	case ERR_FILE_OPEN:
		size = strlen(MSG_HEAD)+strlen(MSG_FILE_OPEN)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_FILE_OPEN);
		level = ERR_LEV;
		break;

	case ERR_FILE_CLOSE:
		size = strlen(MSG_HEAD)+strlen(MSG_FILE_CLOSE)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_FILE_CLOSE);
		level = ERR_LEV;
		break;

	case ERR_FILE_READ:
		size = strlen(MSG_HEAD)+strlen(MSG_FILE_READ)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_FILE_READ);
		level = ERR_LEV;
		break;

	case ERR_FILE_WRITE:
		size = strlen(MSG_HEAD)+strlen(MSG_FILE_WRITE)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_FILE_WRITE);
		level = ERR_LEV;
		break;

	case ERR_FILE_TRUNC:
		size = strlen(MSG_HEAD)+strlen(MSG_FILE_TRUNC)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_FILE_TRUNC);
		level = ERR_LEV;
		break;

	case ERR_FCNTL:
		size = strlen(MSG_HEAD)+strlen(MSG_FCNTL)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_FCNTL);
		level = DBG_LEV;
		break;

	case ERR_PROC_CREATE:
		size = strlen(MSG_HEAD)+strlen(MSG_PROC_CREATE)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_PROC_CREATE);
		level = ERR_LEV;
		break;

	case ERR_DIR_OPEN:
		size = strlen(MSG_HEAD)+strlen(MSG_DIR_OPEN)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_DIR_OPEN);
		level = ERR_LEV;
		break;

	case ERR_REG_EXP:
		size = strlen(MSG_HEAD)+strlen(MSG_REG_EXP)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_REG_EXP);
		level = ERR_LEV;
		break;

	case ERR_SHMGET:
		size = strlen(MSG_HEAD)+strlen(MSG_SHMGET)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SHMGET);
		level = ERR_LEV;
		break;

	case ERR_SHMAT:
		size = strlen(MSG_HEAD)+strlen(MSG_SHMAT)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SHMAT);
		level = ERR_LEV;
		break;

	case ERR_SHMDT:
		size = strlen(MSG_HEAD)+strlen(MSG_SHMDT)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SHMDT);
		level = ERR_LEV;
		break;

	case ERR_SHMCTL:
		size = strlen(MSG_HEAD)+strlen(MSG_SHMCTL)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SHMCTL);
		level = ERR_LEV;
		break;

	case ERR_SEM_ALLOC:
		size = strlen(MSG_HEAD)+strlen(MSG_SEM_ALLOC)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SEM_ALLOC);
		level = ERR_LEV;
		break;

	case ERR_SEM_DEALLOC:
		size = strlen(MSG_HEAD)+strlen(MSG_SEM_DEALLOC)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SEM_DEALLOC);
		level = ERR_LEV;
		break;

	case ERR_SEM_INIT:
		size = strlen(MSG_HEAD)+strlen(MSG_SEM_INIT)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SEM_INIT);
		level = ERR_LEV;
		break;

	case ERR_SEM_WAIT:
		size = strlen(MSG_HEAD)+strlen(MSG_SEM_WAIT)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SEM_WAIT);
		level = ERR_LEV;
		break;

	case ERR_SEM_POST:
		size = strlen(MSG_HEAD)+strlen(MSG_SEM_POST)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_SEM_POST);
		level = ERR_LEV;
		break;

	case ERR_MMAP:
		size = strlen(MSG_HEAD)+strlen(MSG_MMAP)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_MMAP);
		level = ERR_LEV;
		break;

	case ERR_MUNMAP:
		size = strlen(MSG_HEAD)+strlen(MSG_MUNMAP)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_MUNMAP);
		level = ERR_LEV;
		break;

	case ERR_READ_IP:
		size = strlen(MSG_HEAD)+strlen(MSG_READ_IP)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_READ_IP);
		level = ERR_LEV;
		break;

	default:
		size = strlen(MSG_HEAD)+strlen(MSG_UNKNOWN_ERR)+strlen(MSG_SYS_ERR);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg,MSG_HEAD);
		strcat(msg,MSG_UNKNOWN_ERR);
		break;
	}
	//msg non e' mai NULL
	va_start(parameters, pdim);
	for(k=0; k< pdim; k++){
		temp = msg;
		param = va_arg(parameters, char *);
		size += strlen(param)+strlen(MSG_SPACE);
		msg = (char *)getMemory(size+1, CHAR_TYPE);
		memset(msg, '\0', size+1);
		strcat(msg, temp);
		strcat(msg, MSG_SPACE);
		strcat(msg, param);
		free(temp);
		temp = NULL;
	}
	va_end(parameters);
	strcat(msg, MSG_SYS_ERR);

	
	#ifdef _WIN32
	errnumber = GetLastError();
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
				  FORMAT_MESSAGE_FROM_SYSTEM | 
				  FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),
				  0, (LPSTR)&lpMsgBuf,0,NULL);

	fprintf(stderr, msg, (char *)lpMsgBuf, -err_code);
	logMessage(level, msg);
	free(msg);

	if(exitflag){
		fprintf(stderr, MSG_END, -err_code);
		exit(-err_code);
	}
	#else
		fprintf(stderr, msg,strerror(errno),-err_code);
		composedmsg = (char *)getMemory(strlen(msg)+strlen(strerror(errno))+1, CHAR_TYPE);
		memset(composedmsg,'\0', strlen(msg)+strlen(strerror(errno))+1);
		sprintf(composedmsg, msg,strerror(errno),-err_code, errno);
		logMessage(level, composedmsg);

		free(composedmsg);
		composedmsg = NULL;
		free(msg);
		msg = NULL;
	#endif
	if(exitflag == 1){
		fprintf(stderr, MSG_END, -err_code);
		exit(-err_code);
	}
	logMessage(DBG_LEV,"mysocket.notifyError() END");
}
